package com.ruoyi.file.service.impl;

import cn.hutool.core.util.IdUtil;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.file.component.FileConvertorProcessor;
import com.ruoyi.file.component.PublishLayerProcess;
import com.ruoyi.file.domain.*;
import com.ruoyi.file.mapper.TblFileMapper;
import com.ruoyi.file.service.ITblFileDataService;
import com.ruoyi.file.service.ITblFileService;
import com.ruoyi.gis.componets.RasterDatasetComponent;
import com.ruoyi.gis.domain.DatasetRaster;
import com.ruoyi.gis.domain.GisLayer;
import com.ruoyi.gis.service.IDatasetRasterService;
import com.ruoyi.gis.service.IGisLayerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 文件管理Service业务层处理
 *
 * @author rww
 * @date 2023-09-05
 */
@Service
public class TblFileServiceImpl implements ITblFileService
{
    private final Logger logger = LoggerFactory.getLogger(TblFileServiceImpl.class);
    @Autowired
    private TblFileMapper tblFileMapper;
    @Autowired
    private IGisLayerService gisLayerService;
    @Autowired
    private PublishLayerProcess publishLayerProcess;
    @Autowired
    private FileConvertorProcessor fileConvertorProcessor;
    @Autowired
    private ITblFileDataService tblFileDataService;

    @Autowired
    private IDatasetRasterService datasetRasterService;
    @Autowired
    private RasterDatasetComponent rasterDatasetComponent;
    /**
     * 查询文件管理
     *
     * @param id 文件管理主键
     * @return 文件管理
     */
    @Override
    public TblFile selectTblFileById(Long id)
    {
        return tblFileMapper.selectTblFileById(id);
    }

    @Override
    public TblFile selectTblFileDetailById(Long id) {
        return tblFileMapper.selectTblFileDetailById(id);
    }

    @Override
    public void addRasterImages(LoginUser loginUser, FileAddRasterImageDto dto) {
        Long pid = dto.getPid()==null?0:dto.getPid();
        dto.getDataIds().stream().forEach(dataId->{
            DatasetRaster raster = datasetRasterService.selectDatasetRasterByDataId(dataId);
            if(raster!=null){
                TblFile tblFile = tblFileMapper.selectFileByPidAndDataId(pid,dataId);
                if(tblFile==null){
                    tblFile = new TblFile();
                    tblFile.setId(IdUtil.getSnowflakeNextId());
                    tblFile.setPid(pid);
                    tblFile.setOriginalFilename(raster.getName());
                    tblFile.setFileName(raster.getName());
                    tblFile.setFileNameNoExt(raster.getName());
                    tblFile.setFileSize(raster.getFileSize());
                    tblFile.setFileType(TblFile.type_file);
                    tblFile.setPublished(false);
                    tblFile.setPublishable(true);
                    tblFile.setBucket(raster.getBucket());
                    tblFile.setObjectName(raster.getObjectName());
                    tblFile.setUserId(loginUser.getUserId());
                    tblFile.setFromType(TblFile.fromType_raster);
                    tblFile.setRasterId(raster.getId());
                    tblFile.setDataId(dataId);
                    tblFile.setSourceType(raster.getSourceType());
                    tblFile.setAcquisitionDate(raster.getAcquisitionDate());
                    Date date = new Date();
                    tblFile.setCreateTime(date);
                    insertTblFile(tblFile);
                    updateFolderSize(tblFile.getPid());
                }
                if(DatasetRaster.state_undownload.
                        equals(raster.getFileDownloadState())){
                    logger.info("addRasterImages add raster download send request......");
                    //发送下载请求
                    rasterDatasetComponent.sendDownloadDataIdRequest(dataId);
                }else {
                    logger.info("addRasterImages add raster jump download use already download ......");
                }
            }
        });
    }

    /**
     * 查询文件管理列表
     *
     * @param tblFile 文件管理
     * @return 文件管理
     */
    @Override
    public List<TblFile> selectTblFileList(TblFile tblFile)
    {
        return tblFileMapper.selectTblFileList(tblFile);
    }

    /**
     * 新增文件管理
     *
     * @param tblFile 文件管理
     * @return 结果
     */
    @Override
    public int insertTblFile(TblFile tblFile)
    {
        tblFile.setCreateTime(DateUtils.getNowDate());
        return tblFileMapper.insertTblFile(tblFile);
    }

    /**
     * 修改文件管理
     *
     * @param tblFile 文件管理
     * @return 结果
     */
    @Override
    public int updateTblFile(TblFile tblFile)
    {
        tblFile.setUpdateTime(DateUtils.getNowDate());
        return tblFileMapper.updateTblFile(tblFile);
    }

    /**
     * 批量删除文件管理
     *
     * @param ids 需要删除的文件管理主键
     * @return 结果
     */
    @Override
    public int deleteTblFileByIds(Long[] ids)
    {
        for(Long id:ids){
            deleteTblFileById(id);
        }
        return ids.length;
//        return tblFileMapper.deleteTblFileByIds(ids);
    }

    /**
     * 删除文件管理信息
     *
     * @param id 文件管理主键
     * @return 结果
     */
    @Override
    public int deleteTblFileById(Long id)
    {
        logger.info("删除文件...................");
        TblFile tblFile = tblFileMapper.selectTblFileById(id);
        tblFileDataService.deleteDataByFileId(id);
        if(tblFile!=null&&tblFile.getPublished()!=null&&tblFile.getPublished()){
            try {
                logger.info("取消图层发布...................");
                publishLayerProcess.cancelFilePublish(id);
                logger.info("取消图层发布操作成功...................");
            } catch (Exception e) {
                e.printStackTrace();
                logger.info("取消图层发布操作异常...................");
            }
        }
        if(TblFile.type_folder.equals(tblFile.getFileType())){
            logger.info("删除文件夹下的文件...................");
            TblFile query = new TblFile();
            query.setPid(id);
            List<TblFile> tblFiles = tblFileMapper.selectTblFileList(query);
            for(TblFile item:tblFiles){
                try {
                    deleteTblFileById(item.getId());
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("取消图层发布操作异常...................");
                }
            }
            logger.info("删除文件夹对应的图层组...................");
            gisLayerService.deleteGisLayerGroupByFileId(tblFile.getId());
        }
        logger.info("删除文件成功...................");
        return tblFileMapper.deleteTblFileById(id);
    }

    @Override
    public TblFile addFolder(Long userId, Long pid, String fileName) {
        TblFile parentFile = null;
        if(0==pid){
            parentFile = new TblFile();
            parentFile.setId(0L);
        }else {
            parentFile = tblFileMapper.selectTblFileById(pid);
        }
        if (parentFile != null) {
            TblFile query = tblFileMapper.selectByUserIdAndPidAndNameAndType(userId,
                    pid, fileName, TblFile.type_folder);
            if (query != null) return query;
            TblFile folder = new TblFile();
            folder.setId(IdUtil.getSnowflakeNextId());
            folder.setFileType(TblFile.type_folder);
            folder.setFileName(fileName);
            folder.setFilePath(0==pid?userId+"/"+fileName:parentFile.getFilePath()+"/"+fileName);
            folder.setPid(pid);
            folder.setFileSize(0L);
            folder.setUserId(userId);
            Date date = new Date();
            folder.setCreateTime(date);
            tblFileMapper.insertTblFile(folder);
            //同时新增layerGroup
//            gisLayerService.insertGisLayer()
            return folder;
        } else {
            return null;
        }
    }

    @Override
    public long sumFolderSize(Long pid) {
        return tblFileMapper.sumFolderSize(pid);
    }

    @Override
    public void updateFolderSize(Long pid) {
        if(0==pid)return;
        TblFile tblFile = tblFileMapper.selectTblFileById(pid);
        Long size = tblFileMapper.sumFolderSize(pid);
        tblFile.setFileSize(size);
        tblFileMapper.updateTblFile(tblFile);
        updateFolderSize(tblFile.getPid());
    }

    //tif 文件关联layer组
    @Override
    public GisLayer addParentLayer(TblFile tblFile,LoginUser loginUser) {
//        if(tblFile.getPid()==0)return null;//&&tblFile.getFileType().equals(TblFile.type_file)
        if(tblFile.getId()==0)return null;
        TblFile parentFile = selectTblFileById(tblFile.getPid());
        if(parentFile==null)return null;//查找的tblFile.getPid()==0的
        GisLayer layer = gisLayerService.selectGisLayerByFileId(parentFile.getId());
        if(layer!=null)return layer;
        GisLayer gisLayer = new GisLayer();
        gisLayer.setGroup(GisLayer.type_group);
        gisLayer.setFileId(parentFile.getId());
        gisLayer.setLayerName(parentFile.getFileName());
        gisLayer.setLayerTitle(parentFile.getFileName());
        gisLayer.setUserId(loginUser.getUserId());
        gisLayer.setModel(GisLayer.model_file);
        if(0==parentFile.getPid()){
            gisLayer.setParentId(0L);
        }else {
//            TblFile upperFile = selectTblFileById(parentFile.getPid());
            GisLayer parentLayer = addParentLayer(parentFile,loginUser);
            gisLayer.setParentId(parentLayer!=null?parentLayer.getLayerId():0);
        }
        gisLayerService.insertGisLayer(gisLayer);
        return gisLayer;
    }

    @Override
    public List<FilePublishDto> saveFile(LoginUser loginUser, FileAddDto fileAddDto) {
        logger.info("saveFile...........start...............");
        Long userId = loginUser.getUserId();
        List<FilePublishDto> publishFilesMsg = new ArrayList<>();
        for(TFileInfoLocalVO item:fileAddDto.getFiles()){
            TblFile parent = null;
            if(0==fileAddDto.getPid()){
                parent = new TblFile();
                parent.setId(0l);
            }else {
                parent = selectTblFileById(fileAddDto.getPid());
            }
            if(parent!=null){
                List<String> fDirs = new ArrayList<>();
                if(0==fileAddDto.getPid()){
                    fDirs.add(userId+"");
                }
                if(fileAddDto.getDirectory()){
                    String[] folders = item.getRelativePath().split("/");//File.separator
                    //最后一个为文件
                    for(int i=0;i<folders.length-1;i++){
                        fDirs.add(folders[i]);
                        TblFile fileFolder = addFolder(userId,parent.getId(), folders[i]);
                        if(fileFolder!=null){
                            parent = fileFolder;
                        }
                    }
                }
//                if(parent==null){
//                    return AjaxResult.error("添加目录失败");
//                }
                String folder = StringUtils.join(fDirs,"/");
                if(0==parent.getId()){
                }else {
                    folder = parent.getFilePath();
                }
                TblFile entity = new TblFile();
                entity.setId(IdUtil.getSnowflakeNextId());
                entity.setPid(parent.getId());
                entity.setFileName(item.getName());
                entity.setFileSize(item.getSize());
                entity.setUserId(userId);
                entity.setIdentifier(item.getUniqueIdentifier());
                String ext = FileUtils.getExt(item.getName());
                entity.setContentType(ext);
                if(FileUtils.isTifFile(item.getName())){
                    entity.setPublishable(true);
                }else if(FileUtils.isShpFile(item.getName())){
                    entity.setPublishable(true);
                }
                entity.setFileType(TblFile.type_file);
                entity.setBucket(item.getBucket());
                entity.setFilePath(folder);
                entity.setObjectName(item.getObjectName());
                entity.setTaskId(fileAddDto.getTaskId());
                insertTblFile(entity);
                //更新上级目录大小
                updateFolderSize(entity.getPid());
                logger.info("the file is add to db and update folder size.....................");
//                if(0!=parent.getId()){
//                    long folderSize = tblFileService.sumFolderSize(parent.getId());
//                    parent.setFileSize(folderSize);
//                    tblFileService.updateTblFile(parent);
//                }
                if(entity.getPublishable()!=null&&entity.getPublishable()){
                    logger.info("the file is Publishable...........init layer...............");
                    GisLayer gisLayerGroup = null;
                    if(parent.getId()!=0){
                        gisLayerGroup = addParentLayer(entity,loginUser);
                    }
                    FilePublishDto publishDto = new FilePublishDto();
                    publishDto.setPublishFileId(entity.getId());
                    publishDto.setParentLayerId(gisLayerGroup!=null?gisLayerGroup.getLayerId():0L);
                    publishFilesMsg.add(publishDto);
                }
                //is office
                if(FileUtils.isOfficeFile(item.getName())){
                    fileConvertorProcessor.sendConvertFileMsg(entity,"office");
                }else if(FileUtils.isCadFile(item.getName())){
                    fileConvertorProcessor.sendConvertFileMsg(entity,"cad");
                }
            }
        }
        return publishFilesMsg;
    }

    @Override
    public void publishFile(Long id, LoginUser loginUser) {
        TblFile entity = selectTblFileById(id);
        if(entity==null)return;
        if(entity.getPublishable()!=null&&entity.getPublishable()){
            logger.info("the file is Publishable...........init layer...............");
            GisLayer gisLayerGroup =  addParentLayer(entity,loginUser);
            FilePublishDto publishDto = new FilePublishDto();
            publishDto.setPublishFileId(entity.getId());
            publishDto.setParentLayerId(gisLayerGroup!=null?gisLayerGroup.getLayerId():0L);
            publishLayerProcess.sendPublishLayerMessage(publishDto);
        }
    }


}
